package server.command.client;

import app_kvServer.KVServer;
import app_kvServer.ServerMetadata;
import utils.CommonUtil;
import utils.IKeyValueStorage;
import common.messages.KVMessage.StatusType;

public class CommandPut implements ICommand {
	private IKeyValueStorage storage;
	private String key;
	private String value;
	private KVServer server;
	
	public CommandPut(KVServer server, IKeyValueStorage storage, String key, String value) {
		this.key = key;
		this.value = value;
		this.storage = storage;
		this.server = server;
	}
	
	@Override
	public String execute() {
		if (key==null || key.length()==0) {
			return ClientInputHandler.composeClientResponse(StatusType.PUT_ERROR, "ERROR: a key may not be null or empty", "");
		}
		if (storage.isWriteLockEnabled()) {
			return ClientInputHandler.composeClientResponse(StatusType.SERVER_WRITE_LOCK, "Write lock enabled Enabled", "");
		}
		String keyHash = CommonUtil.hashString(key);
		if (KVServer.isInRange(keyHash, server.getRangeStart(), server.getRangeEnd())) {
			boolean keyExisted = storage.containsKey(keyHash);
			if(keyExisted && value.equalsIgnoreCase("null")) {
				storage.remove(keyHash);
				return ClientInputHandler.composeClientResponse(StatusType.DELETE_SUCCESS, key, value);
			}
			StatusType status = keyExisted ? StatusType.PUT_UPDATE : StatusType.PUT_SUCCESS;
			storage.put(keyHash, value);
			return ClientInputHandler.composeClientResponse(status, key, value);
		}
		else {
			/** TODO what if the metadata is out of date? **/
			return ClientInputHandler.composeClientResponse(StatusType.SERVER_NOT_RESPONSIBLE, key, ServerMetadata.marshal(server.getMetadata()));
		}

	}
}
